#pragma once;
/**
 * The EffectManager class encompass the functionality to create effects,
 * from cg effect files and cgFX files.
 */
#include "Object.h"
#include "Events.h"

class Effect;

class EffectManager : public Object
{
public:
    // Create an instance of the effect manager.
    // Returns the instance of the created effect manager.
    static EffectManager& Create();
    // Destroy the instance of the effect manager.
    static void Destroy();

    // Get the instance of the effect manager
    // Asserts if the effect manager hasn't been created.
    static EffectManager& Get();

    // Creates the cg context object.
    // Expects OpenGL to be initialized first.
    virtual bool Initialize();

    // Destroy the cg context.
    // This will also invalidate any Effects
    // that were created with this effect manager.
    virtual void Terminate();

    // Create an Effect instance from an effect file.
    // If the effect couldn't be created, then an invalid effect is returned.
    Effect& CreateEffectFromFile( const std::string& effectFile, const std::string& effectName );

    // Get an effect from the effect manager based on the name that was used to load
    // the effect.
    Effect& GetEffect( const std::string& effectName );

    // Check the loaded effects to see if any of them out out-of-date
    // and if so, reload the effect.
    void ReloadEffects();

    // The error handler for the Cg runtime.
    static void ErrorHandler( CGcontext context, CGerror error, void* appdata );

    // EVENTS
    // If an error occurs in the Cg runtime, this event will be triggered
    RuntimeErrorEvent   RuntimeError;
    // When an effect is loaded (or reloaded), this event will be triggered.
    // Subscribers should subscribe to this event and not the one in the effect class itself.
    EffectLoadedEvent   EffectLoaded;

protected:
    // This is a singleton class and should only be created or destroyed using 
    // the Create and Destroy methods
    // A reference to the object can be retrieved using the Get static method.
    EffectManager();
    virtual ~EffectManager();

    virtual void OnRuntimeError( RuntimeErrorEventArgs& e );
    virtual void OnEffectLoaded( EffectLoadedEventArgs& e );

private:
    typedef std::map< std::string, Effect* > EffectMap;

    bool        m_bIsInitialized;
    // The CG context that will be owned by the effect manager.
    CGcontext   m_cgContext;

    EffectMap   m_Effects;
    
};